﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.Text;
using ElectronicCommerce.Framework.ServiceModel.Configuration;
using ElectronicCommerce.Framework.ServiceModel.WCF.TransferElement;
using ElectronicCommerce.Framework.Utility;

namespace ElectronicCommerce.Framework.ServiceModel.WCF
{
    public class WCFUtility
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static Binding GetBinding(Type serviceType, string serviceName)
        {
            ServiceElement serviceElement
                = ServiceModelConfigHelper.ServiceConfig.GetMixServiceElement(serviceType, serviceName);

            return GetBinding(serviceElement);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceElement"></param>
        /// <returns></returns>
        public static Binding GetBinding(ServiceElement serviceElement)
        {
            AssertUtils.ArgumentNotNull(serviceElement, "serviceElement");

            IGetBindingByConfig handler = BindingFactory.CreateHandler(
                EnumHelper.GetEnumObject<BindingTypeEnum>(serviceElement.Binding.Type));

            return handler.GetBindingMsgByConfig(serviceElement.Binding.Content);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="myServiceClient"></param>
        public static void CloseConnection(object myServiceClient)
        {
            ICommunicationObject o = myServiceClient as ICommunicationObject;
            if (o != null)
            {
                CloseConnection(o);
            }
        }

        /// <summary>
        /// Safely closes a service client connection.
        /// </summary>
        /// <param name="myServiceClient">The client connection to close.</param>
        /// <remarks>
        /// http://msdn.microsoft.com/en-us/library/aa355056.aspx
        /// http://stevesmithblog.com/blog/idisposable-and-wcf/
        /// http://www.infoq.com/cn/news/2009/03/WCF-Dispose
        /// </remarks>
        public static void CloseConnection(ICommunicationObject myServiceClient)
        {
            if (myServiceClient == null || myServiceClient.State != CommunicationState.Opened)
            {
                return;
            }

            try
            {
                myServiceClient.Close();
            }
            catch (CommunicationException ex)
            {
                Debug.Print(ex.ToString());
                myServiceClient.Abort();
            }
            catch (TimeoutException ex)
            {
                Debug.Print(ex.ToString());
                myServiceClient.Abort();
            }
            catch (Exception ex)
            {
                Debug.Print(ex.ToString());
                myServiceClient.Abort();
                throw;
            }
        }
    }
}
